package service

import (
	"context"
	"errors"
	"fmt"
	"gitee.com/chunanyong/logger"
	"gitee.com/chunanyong/zorm"
	"zorm-learn/app/dm/model"
)

// SaveTestTableStruct 保存
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func SaveTestTableStruct(ctx context.Context, testtablestruct *model.TestTableStruct) error {

	// testtablestruct对象指针不能为空
	if testtablestruct == nil {
		return errors.New("testtablestruct对象指针不能为空")
	}
	//匿名函数return的error如果不为nil,事务就会回滚
	_, errSaveTestTableStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始

		_, errSaveTestTableStruct := zorm.Insert(ctx, testtablestruct)

		if errSaveTestTableStruct != nil {
			return nil, errSaveTestTableStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errSaveTestTableStruct != nil {
		errSaveTestTableStruct := fmt.Errorf("service.SaveTestTableStruct错误:%w", errSaveTestTableStruct)
		logger.Error(errSaveTestTableStruct)
		return errSaveTestTableStruct
	}

	return nil
}

// UpdateTestTableStruct 更新
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateTestTableStruct(ctx context.Context, testtablestruct *model.TestTableStruct) error {

	// testtablestruct对象指针或主键<no value>不能为空
	if testtablestruct == nil {
		return errors.New("testtablestruct对象指针或主键<no value>不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTestTableStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTestTableStruct := zorm.Update(ctx, testtablestruct)

		if errUpdateTestTableStruct != nil {
			return nil, errUpdateTestTableStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTestTableStruct != nil {
		errUpdateTestTableStruct := fmt.Errorf("service.UpdateTestTableStruct错误:%w", errUpdateTestTableStruct)
		logger.Error(errUpdateTestTableStruct)
		return errUpdateTestTableStruct
	}

	return nil
}

// UpdateNotZeroTestTableStruct 更新
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateNotZeroTestTableStruct(ctx context.Context, testtablestruct *model.TestTableStruct) error {

	// testtablestruct对象指针或主键<no value>不能为空
	if testtablestruct == nil {
		return errors.New("testtablestruct对象指针或主键<no value>不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTestTableStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTestTableStruct := zorm.UpdateNotZeroValue(ctx, testtablestruct)

		if errUpdateTestTableStruct != nil {
			return nil, errUpdateTestTableStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTestTableStruct != nil {
		errUpdateTestTableStruct := fmt.Errorf("service.UpdateNotZeroTestTableStruct错误:%w", errUpdateTestTableStruct)
		logger.Error(errUpdateTestTableStruct)
		return errUpdateTestTableStruct
	}

	return nil
}

// DeleteTestTableStructById 根据Id删除
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func DeleteTestTableStructById(ctx context.Context, id string) error {
	//id不能为空
	if len(id) < 1 {
		return errors.New("id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errDeleteTestTableStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		finder := zorm.NewDeleteFinder(model.TestTableStructTableName).Append(" WHERE id=?", id)
		_, errDeleteTestTableStruct := zorm.UpdateFinder(ctx, finder)

		if errDeleteTestTableStruct != nil {
			return nil, errDeleteTestTableStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errDeleteTestTableStruct != nil {
		errDeleteTestTableStruct := fmt.Errorf("service.DeleteTestTableStruct错误:%w", errDeleteTestTableStruct)
		logger.Error(errDeleteTestTableStruct)
		return errDeleteTestTableStruct
	}

	return nil
}

// FindTestTableStructById 根据Id查询信息
// ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTestTableStructById(ctx context.Context, id string) (*model.TestTableStruct, error) {
	//id不能为空
	if len(id) < 1 {
		return nil, errors.New("id不能为空")
	}

	//根据Id查询
	finder := zorm.NewSelectFinder(model.TestTableStructTableName).Append(" WHERE id=?", id)
	testtablestruct := model.TestTableStruct{}
	has, errFindTestTableStructById := zorm.QueryRow(ctx, finder, &testtablestruct)

	//记录错误
	if errFindTestTableStructById != nil {
		errFindTestTableStructById := fmt.Errorf("service.FindTestTableStructById错误:%w", errFindTestTableStructById)
		logger.Error(errFindTestTableStructById)
		return nil, errFindTestTableStructById
	}

	if !has {
		return nil, nil
	}

	return &testtablestruct, nil

}

// FindTestTableStructList 根据Finder查询列表
// ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTestTableStructList(ctx context.Context, finder *zorm.Finder, page *zorm.Page) ([]model.TestTableStruct, error) {

	//finder不能为空
	if finder == nil {
		return nil, errors.New("finder不能为空")
	}

	testtablestructList := make([]model.TestTableStruct, 0)
	errFindTestTableStructList := zorm.Query(ctx, finder, &testtablestructList, page)

	//记录错误
	if errFindTestTableStructList != nil {
		errFindTestTableStructList := fmt.Errorf("service.FindTestTableStructList错误:%w", errFindTestTableStructList)
		logger.Error(errFindTestTableStructList)
		return nil, errFindTestTableStructList
	}

	return testtablestructList, nil
}
